[Question]
  [
# The challenge
Given a list of words `["Programming", "Puzzles", "Code", "Golf"]` output the words crossword-style:
```
      P r o g r a m m i n g
      u
      z
      z
  G   l
C o d e
  l   s
  f
```
# The Algorithm
* You have to process the list in the given order.
* The words are printed in alternating orientations, starting **horizontally**.
* The two words intersect at the first letter in the first word which is also present in the second word. If this letter occurs multiple times in the seond word, take the first one.
**Example**:  
`["no", "on"]` becomes:
```
o
n o
```
and **not** 
```
n o
  n
```
# Additional notes
* Adjacent words in the list will have at least one common letter. `["Hi", "there"]` is not a valid input.
* Words will never collide. There will always be enough space to print the a word at the first possible intersection. `["Hello", "there", "end", "hello"]` is not a valid input
* The matching is case-sensitive.
* Words can expand to the left and to the top.
* The letters of the horizontal words have to be separated by one space.
* The input list will contain at least two words.
* All words will match the regex: `[A-Za-z]+`
* You may print as many trailing whitespaces or newlines as you want, as long as the words are correctly chained.
* On the other hand you may not add additional leading whitespaces. The word which floats to the left the most has zero leading spaces, the other lines have so many leading spaces that it all lines up correctly.
* You program has to be able to deal with an arbitrary amount of words
# Rules
* Function or full program allowed.
* [Default rules](https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods) for input/output.
* [Standard loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) apply.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so lowest byte-count wins. Tiebreaker is earlier submission.
# Test cases
Input list on the first line, output starts on the second line.
```
["Stack", "Exchange"]
    E
    x
    c
    h
S t a c k
    n
    g
    e
```
```
["This", "site", "graduated", "finally"]
    f
    i       s
    n   T h i s
g r a d u a t e d
    l       e
    l
    y
```
**Happy Coding!**
  
[Answer]
# JavaScript (ES6) 253
As an anonymous function with an array parameter
```
z=>(z.map((w,i)=>(i&&[...p].some((c,j)=>~(k=w.search(c))?i&1?[y-=k,x+=j]:[y+=j,x-=k]:0),[p=w,x<t?t=x:x,y<u?u=y:y]),t=u=x=y=0).map(([w,x,y],i)=>{x-=t,y-=u;for(c of w)(o[y]=o[y]||[])[x]=c,i&1?y++:x++},o=[]),o.map(r=>[...r].map(x=>x||' ').join` `).join`
`)
```
```
F=z=>(z.map((w,i)=>(i&&[...p].some((c,j)=>~(k=w.search(c))?i&1?[y-=k,x+=j]:[y+=j,x-=k]:0),[p=w,x<t?t=x:x,y<u?u=y:y]),t=u=x=y=0).map(([w,x,y],i)=>{x-=t,y-=u;for(c of w)(o[y]=o[y]||[])[x]=c,i&1?y++:x++},o=[]),o.map(r=>[...r].map(x=>x||' ').join` `).join`
`)
// Less golfed
F=z=>(
  z.map( // Step 1, find intersection points and relative position
    (w,i)=>(
      i && // for each word after thw first, find position respect the previous word
      [...p].some((c,j)=> // scan prec word using .some to exit at the first intersection found
         ~(k=w.search(c)) // search current char of p inside w
         ?i&1 // calc position, odd is vertical, even is horizontal
           ?[y-=k, x+=j] // returning an array so to have a truthy value
           :[y+=j, x-=k] // returning an array so to have a truthy value
         :0 // false = not found, continue the scan
      ),
      [p=w, // set preceding word
       x<t?t=x:x, // keep trace of min x
       y<u?u=y:y  // keep trace of min y
      ] // meanwhile, return word, x and y to be used in next step 
    ), t=u=x=y=0 // initializations
  )
  .map(([w,x,y],i)=>{ // Step 2, put char into the output array
      x-=t,y-=u; // normalize position respect to min values
      for(c of w) // for each char in word, set in the output array at the right place
        (o[y]=o[y]||[])[x]=c, 
        i&1?y++:x++ // increment x or y, again odd is vertical, even is horizontal
    }, o=[] // initialization of output array
  ),
  // Step 3, add the missing spaces and newlines
  o.map(r=>[...r].map(x=>x||' ').join` `).join`\n`
)
O.textContent=F(["This", "site", "graduated", "finally"])
```
```
<pre id=O></pre>
```
[Answer]
# ANSI C, 385 ~~390~~ Characters
```
int N,a=1,x,y,d=1,u,k,l;int main(int c,char**v){for(;a<c;)N+=strlen(v[a++]);int H=N*2,W=N*4,m=H,n=N,q=m,w=n;char*p,F[W][H],*o;memset(F,32,W*H);for(a=1;a<c;a++){q=(x=m)<q?m:q;w=(y=n)<w?n:w;m=-1;for(p=v[a];*p;p++){F[x][y]=*p;if(m<0&&a<c-1&&(o=strchr(v[a+1],*p))){u=o-v[a+1];m=d?x:x-u*2;n=d?y-u:y;}if(d)x+=2;else y++;}d=!d;}for(l=w;l<H;l++){for(k=q;k<W;)putchar(F[k++][l]);putchar(10);}}
```
Call it like this: `./crossword This site graduated finally`
Ungolfed version:
```
int N,a=1,x,y,d=1,u,k,l;
int main(int c, char **v) {
    for(;a<c;)
        N+=strlen(v[a++]);
    int H = N*2, W = N*4, m = H, n = N, q=m, w=n;
    char *p,F[W][H], *o;
    memset(F, 32, W*H);
    for (a=1; a < c; a++) {
        q=(x=m)<q?m:q;
        w=(y=n)<w?n:w;
        m=-1;
        for (p=v[a]; *p; p++) {
            F[x][y] = *p;
            if (m<0&&a<c-1&&(o = strchr(v[a+1], *p))) {
                u = o-v[a+1];
                m = d ? x : x-u*2;
                n = d ? y-u : y;
            }
            if (d) x+=2; else y++;
        }
        d=!d;
    }
    for (l = w; l < H; l++) {
        for (k = q; k < W;)
            putchar(F[k++][l]);
        putchar(10);
    }
}
```
Thank you tucuxi for the tips!
]