John the Ripper also does something like this, but it's a bit of a pain to set up.
Wordlist rules are only usable for this when your list of words is
very short - or, if you have different lists for different "word
positions", when all but one list are very short (it is OK for one of
these lists to be long - you'd place that one in your wordlist file).
...and so on for two-word combinations. For that, you'll need to
place your "first" words into a wordlist file, one per line:
cat dog bird cow
and you need to create wordlist rules out of your "second" words,
using the "append character" command:
[List.Rules:Wordlist] $c$a$t $d$o$g $b$i$r$d $c$o$w
Then running JtR produces:
$ john -w=w --rules --stdout catcat dogcat birdcat cowcat catdog
dogdog ... cowcow words: 16 time: 0:00:00:00 100% w/s: 1600
For three-word combinations, you may have JtR apply the rules for a
$ john -w=w --rules --stdout > w2 words: 16 time: 0:00:00:00 100%
w/s: 1600 current: cowcow $ john -w=w2 --rules --stdout catcatcat
dogcatcat birdcatcat cowcatcat catdogcat ... birdcowcow
cowcowcow words: 64 time: 0:00:00:00 100% w/s: 6400 current:
Of course, in practice your final invocation of "john" won't use the
"--stdout" option, but it will instead include the filename for your
file with the password hash. I am using "--stdout" in these examples
to show what candidate "passwords" would be tried.