It depends on what you mean by “subshell”. And you may be missing the point in your “every command in a pipeline” bullet.
 Any time you run any (external) program
(i.e., a script or binary executable, in contrast to a shell builtin),
unless you use exec program,
you run it in a sub-process (or processes). 
The shell forks and executes the program. 
ls | wc does not create a subshell any more than ls and wc do alone.
The interesting thing is that including it in a pipeline can cause a shell builtin to run in a subshell. Consider this example:
$ read v cat # This is input typed by the user. $ echo "$v" cat $ echo cougar | read v $ echo "$v" cat
 The second read v command is run in a subshell
because it is part of the echo cougar | read v pipeline. 
Therefore, the value cougar is lost, and $v retains its first value.
Likewise, commands like
$ echo foo | cd /
$ cd / | cat
$ echo foo | exit
$ exit | cat
do not affect the main shell.
 
                