Delete strings: {name, John, John Doe, Doe} to {name, John Doe}

strings = {"name", "John", "John Doe", "Doe"};

Pick[strings,
 BitAnd @@ (IdentityMatrix[Length[strings]] +
    Boole[Outer[StringFreeQ, strings, strings]]), 1]

{"name", "John Doe"}

Or equivalently:

Pick[strings,
 MapIndexed[StringFreeQ[Delete[strings, #2], #] &, strings],
 ConstantArray[True, Length[strings] - 1]]

The code below matches only whole words:

strings = {"to", "tomorrow", "name", "John", "John Doe", "Doe"}

Pick[strings,
 And @@@ MapIndexed[StringFreeQ[Delete[strings, #2],
     " " | StartOfString ~~ # ~~ EndOfString | " "] &, strings]]

{"to", "tomorrow", "name", "John Doe"}


I'll assume that the list will contain strings, not variables:

L = {"name", "John", "John Doe", "Doe"};

Delete element sequences like {"John", "Doe"} that are together contained in a single string "John Doe":

ClearAll[f];
SetAttributes[f, Orderless];
(f[Sequence @@ #, x___] = f[x]) & /@ Select[StringSplit /@ L, Length[#] > 1 &];
f[x___] = {x};
f @@ L

{"John Doe", "name"}

This method does not keep the original sorting order of the list. If this order needs to be kept, we can replace the last line with

SortBy[f @@ L, Position[L, #][[1, 1]] &]

{"name", "John Doe"}

update

In order to deal with multiple mentions of "John", for example, a slight modification to the Orderless pattern using Repeated ..:

L = {"name", "John", "John", "John Doe", "Doe"};
ClearAll[f];
SetAttributes[f, Orderless];
(f[Sequence @@ Thread[# ..], x___] = f[x]) & /@
  Select[StringSplit /@ L, Length[#] > 1 &];
f[x___] = {x};
SortBy[f @@ L, Position[L, #][[1, 1]] &]

{"name", "John Doe"}


# /. Flatten[Cases[#, 
      x_ /; StringContainsQ[x, " "] :> 
       Thread[StringSplit[x] -> Nothing]]] &[{"name", "John", 
  "John Doe", "Doe"}]

{"name", "John Doe"}