Here's another way to do what you want, without creating an intermediate %keepers hash:
use strict;
use warnings;
use Data::Dumper;
# Data Structure
my %h = (
'a' => 'z',
'b' => 'y',
'c' => 'x',
'd' => 'w',
);
my @to_keep = qw{ a c };
%h = map { $_ => $h{$_} } @to_keep;
print Dumper \%h;
Update: If by chance your @to_keep array might contain elements that do not necessarily occur as keys in your input hash, it would probably be better to change the penultimate line to:
%h = map { $_ => $h{$_} } grep { defined $h{$_} } @to_keep;