Vertically collapse text

Pyth, 10 bytes

jb_.T.T_.z

Try it online in the Pyth Compiler/Executor.

Idea

We can achieve the desired output by applying four simple transformations:

  1. Reverse the order of the lines:

    Golf
    Code
    &
    Puzzles
    Programming
    
  2. Transpose rows and columns:

    GC&PP
    oour
    ldzo
    fezg
    lr
    ea
    sm
    m
    i
    n
    g
    

    This top justifies, collapsing the original columns.

  3. Transpose rows and columns:

    Golflesming
    Coderam
    &uzz
    Prog
    P
    
  4. Reverse the order of the lines:

    P
    Prog
    &uzz
    Coderam
    Golflesming
    

Code

        .z  Read the input as a list of strings, delimited by linefeeds.
       _    Reverse the list.
   .T.T     Transpose the list twice.
  _         Reverse the list.
jb          Join its strings; separate with linefeeds.

Haskell, 62 bytes

import Data.List
p=reverse;o=transpose
f=unlines.p.o.o.p.lines

I'm very mature.


Python 2, 104 bytes

l=[]
for x in input().split('\n'):n=len(x);l=[a[:n]+b[n:]for a,b in zip(l+[x],['']+l)]
print'\n'.join(l)

An iterative one-pass algorithm. We go through each line in order, updating the list l of lines to output. The new word effectively pushes from the bottom, shifting all letters above it one space. For example, in the test case

Programming
Puzzles
&
Code
Golf

after we've done up to Code, we have

P
Prog
&uzzram
Codelesming

and then adding Golf results in

P
Prog
&uzz
Coderam
Golflesming

which we can view as the combination of two pieces

P     |
Prog  |
&uzz  |
Code  | ram
Golf  | lesming

where the first piece got shifted up by golf. We perform this shifting with a zip of the output list with the element at the end (left side) and output list precedence by a blank line (right side), cutting off each part at the length of the new element.

It might seem more natural to instead iterate backwards, letting new letters fall from the top, but my attempt at that turned out longer.

For comparison, here's a zip/filter approach, with map(None,*x) used for iziplongest (109 bytes):

f=lambda z:[''.join(filter(None,x))for x in map(None,*z)]
lambda x:'\n'.join(f(f(x.split('\n')[::-1]))[::-1])