IMHO the best way is to try to load/require the GEM and rescue the Exception, as Ray has already shown. It's safe to rescue the LoadError exception because it's not raised by the GEM itself but it's the standard behavior of the require command.
You can also use the gem command instead.
begin
gem "somegem"
# with requirements
gem "somegem", ">=2.0"
rescue GEM::LoadError
# not installed
end
The gem command has the same behavior of the require command, with some slight differences. AFAIK, it still tries to autoload the main GEM file.
Digging into the rubygems.rb file (line 310) I found the following execution
matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
report_activate_error(gem) if matches.empty?
It can provide you some hints about how to make a dirty check without actually loading the library.