Além do problema que você está perguntando, seu script tem uma grande falha, pois faz uma passagem completa através de 'foo' para cada linha em 'remove.txt'. Isso é extremamente ineficiente. A melhor maneira de fazer isso é ler em 'remove.txt', construir uma única expressão regular longa e usá-la uma vez para editar 'foo'.
A maneira mais simples de fazer isso é empurrar as strings de busca para um array e então 'join ()' o array com um '|' (regexp "ou") para criar uma string que possa ser usada como expressão regular.
Aqui está um script que faz isso e corrige seu problema original.
#! /usr/bin/perl
use strict;
use warnings;
# first construct a regular expression containing every
# line that needs to be removed. This is so we only have
# to run a single pass through $infile rather than one
# pass per line in $removefile.
my @remove = ();
my $removefile='remove.txt';
open(REMFILE,"<",$removefile) || die "couldn't open $removefile: $!\n";
while(<REMFILE>) {
chomp;
next if (/^\s*$/);
push @remove, $_;
};
close(REMFILE);
# choose one of the following two lines depending on
# whether you want to remove only entire lines or text
# within a line:
my $remove = '^(' . join("|",@remove) . ')$';
#my $remove = join("|",@remove);
# now remove the unwanted text from all lines in $infile
my $infile = 'foo';
system('perl','-p','-i','-e',"s/$remove//g",$infile);
# if you want to delete matching lines, try this instead:
#system('perl','-n','-i','-e',"print unless /$remove/",$infile);