Stretching Words

Brainfuck, 46 45 (63 with printable characters in input)

Compatible with Alex Pankratov's bff (brainfuck interpreter used on SPOJ and ideone) and Thomas Cort's BFI (used on Anarchy Golf).

The printable version takes the array first as a string, followed by a tab, followed by the starting string with no trailing newline.

Demonstration on ideone.

-[+>,---------]
<[++++++++<]
<,+
[
  -.
  [>+>-<<-]
  >>
  [
    <[>+<-]
  ]
  <[.[-]]
  ,+
]

We can save some bytes by using \x00 as a separator instead of tab:

,[>,]
<[<]
<,+
[
  -.
  [>+>-<<-]
  >>
  [
    <[>+<-]
  ]
  <[.[-]]
  ,+
]

CJam, 15 bytes

rr{_C#)/(C@s}fC

Try it online.

How it works

rr              e# Read two whitespace-separated tokens from STDIN.
  {         }fC e# For each character C in the second string.
   _            e#   Duplicate the first string.
    C#          e#   Compute the index of the character in the string.
      )/        e#   Add 1 and split the string in slice of that size.
        (       e#   Shift out the first slice.
         C      e#   Push the character.
          @     e#   Rotate the remainder of the string in top of the stack.
           s    e#   Stringify (concatenate the slices).

C, 62 bytes

f(char*s,char*c){while(*s-*c||putchar(*c++),*s)putchar(*s++);}

Well, this is surprisingly competetive.

We define a function f(char*, char*) that takes the string as its first input and the array of characters to duplicate as its second input.

Some testing code:

int main (int argc, char** argv) {
    f("onomatopeia", "oao");
    return 0;
}

Which prints:

oonomaatoopeia

Try it online!

If it is acceptable to submit a macro rather than a function, the following #define g(s,c) is just 58 bytes, but requires s and c to be actual pointers:

#define g(s,c)while(*s-*c||putchar(*c++),*s)putchar(*s++);