#Javascript (ES6), 64 bytes

<!-- language: lang-js -->

    a=>a.reduce((p,c)=>p+c.match(/(.+?)\s+#/)[1].slice(p.length),'')

Takes input as an array of strings.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    F=a=>a.reduce((p,c)=>p+c.match(/(.+?)\s+#/)[1].slice(p.length),'')

    input.oninput = update;
    update();

    function update() {
      try {
        output.innerHTML = F(input.value.trim().split`
    `);
      } catch(e) {
        output.innerHTML = 'ERROR: INVALID INPUT';
      }
    }

<!-- language: lang-css -->

    textarea {
      width: 100%;
      box-sizing: border-box;
      font-family: monospace;
    }

<!-- language: lang-html -->

    <h2>Input:</h2>
    <textarea id="input" rows="8">
    a                #Explanation of what 'a' does
     bc              #Bc
       d             #d
        e            #Explanation of e
         fgh         #foobar
            ij       #hello world
              k      #etc.
               l     #so on
                mn   #and
                  op #so forth
    </textarea>
    <hr />
    <h2>Output:</h2>
    <pre id="output">
    </pre>

<!-- end snippet -->