# Julia, <s>165</s> <s>155</s> <s>151</s> <s>129</s> 102 bytes <!-- language-all: lang-default --> g(s,d=[])=join(filter(i->i!=0,[(c=lcfirst(w)[1])∈d?0:(d=[d;c];w)for w=split(s,r"\W",keep=1<0)])," ") This is a function that accepts a string and returns a string. Ungolfed: function g(s, d=[]) # Split the string into an array on unwanted characters, then for # each word, if the first letter has been encountered, populate # this element of the array with 0, otherwise note the first letter # and use the word. This results in an array of words and zeros. x = [(c = lcfirst(w)[1]) ∈ d ? 0 : (d = [d; c]; w) for w = split(s, r"\W", keep=1<0)] # Remove the zeros, keeping only the words. Note that this works # even if the word is the string "0" since 0 != "0". z = filter(i -> i != 0, x) # Join into a string and return return join(z, " ") end Saved 53 bytes with help from Sp3000!