List::MoreUtils has a function called any that uses a syntax similar to grep, but stops its internal loop the first time the criteria are met. The advantage to this behavior is that far fewer iterations will be required (assuming random distribution of intersections).
An additional advantage of any is code clarity: It is named for what it does. Perl Best Practices discourages using grep in Boolean context because the assumed use for grep is to return a list of elements that match. It works in Boolean context, but the intent of the code is less clear to a reader than any, which is designed specifically for Boolean usage.
It is true that any adds a dependency on List::MoreUtils. However, List::MoreUtils is one of those modules that is so ubiquitous, it is highly likely to already be installed.
Here's an example:
use List::MoreUtils qw( any );
my %foo = ( foo => 1, bar => 1 );
my @cmp0 = qw( foo baz );
my @cmp1 = qw( baz blargh );
print "\@cmp0 and %foo have an intersection.\n"
if any { exists $foo{$_} } @cmp0;
print "\@cmp1 and %foo have an intersection.\n"
if any { exists $foo{$_} } @cmp1;
Another option is the ~~ Smart Match Operator, which became available in Perl 5.10.0 and newer. It could be used like this:
my %foo = ( foo => 1, bar => 1 );
my @cmp0 = qw( foo baz );
my @cmp1 = qw( baz blargh );
print "\@cmp0 and %foo have an intersection.\n" if @cmp0 ~~ %foo;
print "\@cmp1 and %foo have an intersection.\n" if @cmp1 ~~ %foo;
With smartmatch, you eliminate the List::MoreUtils dependency in favor of a minimum Perl version dependency. It's up to you to decide whether the code is as clear as any.
keys %foois a list and very much not an array. An array is a Perl variable which can take the place of a list, but it can also do a lot of things an array can't do. See What is the difference between a list and an array?