To ignore the elements in the container that have only null/empty members (the container's members, members) you can create a custom serializer for Container. Custom serializers are great because they give you ultimate control of how an object is written, but this can also lead to code that is difficult to maintain. I say this because with Jackson you can accomplish practically anything with a custom de/serializer, but there is usually a cleaner way (through annotations for example) for most problems. For this, the OP requested guidance on writing a custom serializer, and I don't know a simpler way to accomplish the desired behavior.
Create a Module and Custom Serializer
A Jackson Module is used to encapsulate a deserializer and serializer for a single object. For this example only a serializer is needed, but if you wanted to add a deserializer for Container you could just add it alongside the serializer inside of ContainerModule. The following code defines a serializer for Container that will only write element1 and element2 if at least one of their members are non-null:
public class ContainerModule extends SimpleModule {
    private static final String NAME = "ContainerModule";
    public ContainerModule() {
        super(NAME);
        addSerializer(Container.class, new ContainerSerializer());
    }
    public static class ContainerSerializer extends JsonSerializer<Container> {
        @Override
        public void serialize(Container container, JsonGenerator jg, SerializerProvider serializers) throws IOException {
            if (container != null) {
                // start object and write description
                jg.writeStartObject();
                jg.writeStringField("description", container.description);
                // only write Element1 if one of its members exist
                Element1 element1 = container.element1;
                if (element1 != null) {
                    if (!Strings.isNullOrEmpty(element1.f11)
                            && !Strings.isNullOrEmpty(element1.f12)) {
                        jg.writeFieldName("element1");
                        jg.writeObject(element1);
                    }
                }
                // only write Element2 if one of its members exist
                Element2 element2 = container.element2;
                if (element2 != null) {
                    if (!Strings.isNullOrEmpty(element2.f21)
                            && !Strings.isNullOrEmpty(element2.f22)) {
                        jg.writeFieldName("element2");
                        jg.writeObject(element2);
                    }
                }
                // close the Container object
                jg.writeEndObject();
            }
        }
    }
}
Register the Custom Serializer
The serializer can be registered globally on the ObjectMapper or on the class using @JsonDeserialize.
ObjectMapper Registration
ObjectMapper om = new ObjectMapper()
        .registerModule(new ContainerModule());
Class-level Registration
@JsonSerialize(using = ContainerModule.ContainerSerializer.class)
public class Container {
    String description;
    Element1 element1;
    Element2 element2;
}
This should produce the following results:
// Full container
{
  "description" : "an awesome description",
  "element1" : {
    "f11" : "f11 value",
    "f12" : "f12 value"
  },
  "element2" : {
    "f21" : "f21 value",
    "f22" : "f22 value"
  }
}
// Null Element1 properties
{
  "description" : "an awesome description",
  "element2" : {
    "f21" : "f21 value",
    "f22" : "f22 value"
  }
}
// Null Element2 properties
{
  "description" : "an awesome description",
  "element1" : {
    "f11" : "f11 value",
    "f12" : "f12 value"
  }
}
// Null Element1 and 2 properties
{
  "description" : "an awesome description"
}