I think this is because some tools print the usage message to stderr rather than stdout (ironically I couldn't find an example while typing up this reply). Try:
$ foo -h 2>&1 | grep bar
$ foo -h 2>&1 | grep bar
$ zfs -h | grep help
(Edit: ah, not a very fair example, and a topical one too :)