Merging word streams from files
"Need at least two file arguments: Destination Source {Source {Source {...}}}"


I think an easier way of documenting that, at least for *nix, is:

"Need at least two file arguments: DESTINATION [SOURCE]..."


You can also turn the Paths in your main() method into a Stream too:

public class Linemerge {
    // ...

    // suggestion note: had to wrap IOException -&gt; UncheckedIOException too
    private static void merge(Path source, Set&lt;String&gt; seen, BufferedWriter writer) {
        try (Stream&lt;String&gt; words = Files.lines(source)) {
            words.filter(seen::add).forEach(word -&gt; writeWord(writer, word));
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    private static final Predicate&lt;Path&gt; FILTER =
            f -&gt; Files.isRegularFile(f) &amp;&amp; Files.isReadable(f);

    private static void checkPath(Path path) {
        System.out.println((FILTER.test(path) ? "Merging"
                : "Unable to read (and ignoring)") + " " + path);
    }

    public static void main(String[] args) {
        if (args.length &lt; 2) {
            throw new IllegalArgumentException(
                    "Need at least two file arguments: DESTINATION [SOURCE]...");
        }
        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(args[0]))) {
            Set&lt;String&gt; seen = new HashSet&lt;&gt;();
            Stream.of(args).skip(1).map(Paths::get).peek(Linemerge::checkPath)
                    .filter(FILTER).forEach(f -&gt; merge(f, seen, writer));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}