Substituir loop aninhado pelo Java 8 flatmap

Estou tentando usar o flatmap para fazer um loop aninhado com a API do Stream, mas não consigo entender. Como exemplo, quero recriar o seguinte loop:

List<String> xs = Arrays.asList(new String[]{ "one","two", "three"});
List<String> ys = Arrays.asList(new String[]{"four", "five"});

System.out.println("*** Nested Loop ***");
for (String x : xs)
    for (String y : ys)
        System.out.println(x + " + " + y);

Eu posso fazer assim, mas isso parece feio:

System.out.println("*** Nested Stream ***");
xs.stream().forEach(x ->
    ys.stream().forEach(y -> System.out.println(x + " + " + y))
);

O Flatmap parece promissor, mas como posso acessar a variável no loop externo?

System.out.println("*** Flatmap *** ");
xs.stream().flatMap(x -> ys.stream()).forEach(y -> System.out.println("? + " + y));

Resultado:

*** Nested Loop ***
one + four
one + five
two + four
two + five
three + four
three + five
*** Nested Stream ***
one + four
one + five
two + four
two + five
three + four
three + five
*** Flatmap *** 
? + four
? + five
? + four
? + five
? + four
? + five

questionAnswers(3)

yourAnswerToTheQuestion