You do it exactly the way you have shown:
somecommand | tee >(othercommand)
The output of somecommand would be written to the input of othercommand and to standard output.
The issue with your echo 'bar' process substitution is that it doesn't care about the input that comes via tee from echo 'foo', so it just outputs bar as quickly as it can and terminates. The tee utility then tries to write to it, but fails and therefore terminates (from receiving a PIPE signal) before it writes the string to standard output. Or, tee may have time to write the data to the process substitution, in which case both bar and foo would be printed on standard output, it's not deterministic.
You need to make sure that the command in the process substitution actually reads the data sent to it (otherwise, what would be the point of sending it data?) As Uncle Billy suggests in comments, this is easily arranged in your example by letting the process substitution simply use cat >/dev/null (assuming you're not interested in the data coming from tee):
echo 'foo' | tee >(cat >/dev/null; echo 'bar')
or
echo 'foo' | tee >(echo 'bar'; cat >/dev/null)
(these two variations would vary only in the order of the final output of the two strings)
echo 'foo' | tee >(echo 'bar')printsbarandfoofor me.echo foo,echo barandteecommands will be started and finished, and that's unpredictable. Ifecho barfinishes beforeteetries to write anything into its pipe,teewill be killed by aSIGPIPE.echo foo | tee >(echo bar; cat >/dev/null)in your second example