Update: I see I wasn't explicit enough.
Haskell has a permutations function that would help:
import Data.List
permutations ["hel","lo","bye"] ==
[["hel","lo","bye"],["lo","hel","bye"],["bye","lo","hel"],
["lo","bye","hel"],["bye","hel","lo"],["hel","bye","lo"]]
If you want each permutation concatenated, use
map concat (permutations ["hel","lo","bye"]) ==
["hellobye","lohelbye","byelohel","lobyehel","byehello","helbyelo"]
If you actually want combinations of two substrings (like your example output) instead of all permutations of substrings, as @Sven noticed, use the Math.Combinatorics.Graph module and:
map concat (combinationsOf 2 ["hel","lo","bye"])
That matches your example data in some respects but not others. I could go on to speculate that you want "all possible strings" as the title says, or all permutations of two-token subsets, or what have you, but it's kind of pointless to speculate since you've already accepted an answer.