proc filter {list script} {
set res {}
foreach e $list {if {[uplevel 1 $script $e]} {lappend res $e}}
set res
}

Testing, with a simple way to do intersection:

proc in {list e} {expr {[lsearch -exact $list $e]>=0}}
% filter {a b c} {in {b c d}}
b c

lpz 2013-06-09: The elements I use have spaces, so I changed the filter routine to:

proc filter {list script} {
set res {}
foreach e $list {if {[uplevel 1 $script [list $e]]} {lappend res $e}}
set res
}

Testing

% filter { {s pace} x d} {in {{s pace} a b c d e}}
{s pace} d

smh2 2006-08-26: Here is a routine based on this to find the intersection of many lists:

proc intersection { items } {
set res [lindex $items 0] ; # start with the first sub-list
foreach item [lrange $items 1 end] { ; # loop through the rest
set res [filter $res {in $item}] ; # and filter each new subset against the next
}
set res
}