When life gives you lemons, make lemonade
JavaScript (ES6), 159 157 155 162 bytes

Edit: +7 bytes to "output what was do-able with the letters given" rather than throwing out an error



A recursive function that returns the modified string.

f=(s,a=s.split(/(lemon)/i),n=(a.length-1)*1.5)=&gt;n?f(n,a.map((s,i)=&gt;i&amp;1|!n||(a[i]=s.replace([/a/i,/e/i,/d/i][n%3],c=&gt;(a[--n/3&lt;&lt;1|1]+=c,''))))&amp;&amp;a,n-(n==s)):a.join``


How it works

The expression s.split(/(lemon)/i) splits the input string on lemon but preserves the capture groups in the result.

For instance, "foo lemon bar LEMON baz".split(/(lemon)/i) will produce the array [ 'foo ', 'lemon', ' bar ', 'LEMON', ' baz' ].

We recursively iterate on this array, extracting the characters a, d and e or their uppercase counterparts from the entries located at an even position, and appending them to the entries located at an odd position.

Commented

f = (                                   // given:
  s,                                    //   s = input string or previous value of 'n'
  a = s.split(/(lemon)/i),              //   a = split array, as described above
  n = (a.length - 1) * 1.5              //   n = total number of characters to be found
) =&gt;                                    //
  n ?                                   // if there's still at least one character to find:
    f(                                  //   do a recursive call with:
      n,                                //     1) the current value of 'n'
      a.map((s, i) =&gt;                   //     2) an updated version of 'a', where
        i &amp; 1 | !n || (                 //       for even positions:
          a[i] = s.replace(             //         we look for the next character
            [/a/i, /e/i, /d/i][n % 3],  //           'a', 'e' or 'd' (case insensitive)
            c =&gt; (                      //           append it to
              a[--n / 3 &lt;&lt; 1 | 1] += c, //           one of the entries at an odd position
              ''                        //           and remove it from the original entry
            )                           //           end of replace() callback
          )                             //         end of replace()
        )                               //       end of position condition
      ) &amp;&amp; a,                           //     end of map() -&gt; yield the updated 'a'
      n -                               //     3) the updated value of 'n', skipping the
      (n == s)                          //        current character if not found at all
    )                                   //   end of recursive call
  :                                     // else:
    a.join``                            //   success: join 'a' and return it


Demo



f=(s,a=s.split(/(lemon)/i),n=(a.length-1)*1.5)=&gt;n?f(n,a.map((s,i)=&gt;i&amp;1|!n||(a[i]=s.replace([/a/i,/e/i,/d/i][n%3],c=&gt;(a[--n/3&lt;&lt;1|1]+=c,''))))&amp;&amp;a,n-(n==s)):a.join``

console.log(f("I found a lemon when I was a kid"))
console.log(f("I found a lemon when I was a kid. I found another lemon when I was older."))
console.log(f("bdblemon"))
console.log(f("he hAD lemOn"))