## brainfuck, 99 bytes

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

Formatted:

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

Expects input of the form `1,23,4` without a trailing newline (the language doesn't allow input via command line arguments), and outputs the subsets in the same format (sometimes with a trailing comma, as allowed by the spec) on separate lines. The first line printed will always be empty, signifying the empty set.

[Try it online.](http://brainfuck.tryitonline.net/#code=Kz4-PitbWzwrPj4rPC1dKytbPi08LS0tLS0tXT4tWz5dPDxbPj4rPl0-LF0rKysrKysrKysrW1tbPF08XT4-Wy1bPlsuPl1dPFs8XT4rWz5dPl08PC5bPDxbPF0-LV0rKz5d&input=MSwyMyw0LDU)

The basic idea is to place a bit next to each element, then repeatedly increment the binary number while printing the corresponding subset before each increment. A sentinel bit is placed at the beginning to facilitate terminating the program.

Each bit is encoded as one plus its value; i.e., it can be either `1` or `2`. The tape is laid out with the bit before each element and a single zero cell between each pair of elements. The comma is included on the tape for non-final elements, so that we don't need to do anything special to print delimiters.